﻿/**************************************************************
 *
 * 唯一标识：397c8b4e-60a5-4564-9f4d-0d0558c7c96a
 * 命名空间：Sgr.Caching.Services
 * 创建时间：2023/8/23 7:21:17
 * 机器名称：DESKTOP-S0D075D
 * 创建者：antho
 * 电子邮箱：fengqinhua2016@163.com
 * 描述：
 *
 **************************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Sgr.Caching.Services
{
    /// <summary>
    /// 缓存管理接口，提供缓存的设置、获取、移除和清理功能。
    /// </summary>
    public interface ICacheManager : IDisposable
    {
        /// <summary>
        /// 是否为本地缓存。
        /// </summary>
        bool IsLocalCache { get; }

        /// <summary>
        /// 设置缓存项。
        /// </summary>
        /// <param name="key">缓存键。</param>
        /// <param name="obj">缓存对象，支持null值。当为null时会使用较短的过期时间。</param>
        /// <param name="cacheEntryOptions">缓存项配置选项。</param>
        void Set(string key, object? obj, CacheEntryOptions? cacheEntryOptions = null);

        /// <summary>
        /// 异步设置缓存项。
        /// </summary>
        /// <param name="key">缓存键。</param>
        /// <param name="obj">缓存对象，支持null值。当为null时会使用较短的过期时间。</param>
        /// <param name="cacheEntryOptions">缓存项配置选项。</param>
        /// <param name="token">取消令牌。</param>
        /// <returns>表示异步操作的任务。</returns>
        Task SetAsync(string key, object? obj, CacheEntryOptions? cacheEntryOptions = null, CancellationToken token = default);

        /// <summary>
        /// 尝试从缓存中获取指定键的值
        /// </summary>
        /// <typeparam name="TItem">缓存项的类型</typeparam>
        /// <param name="key">缓存键</param>
        /// <returns>
        /// 返回一个元组，包含：
        /// - Success：表示是否成功获取到缓存项
        /// - Value：缓存项的值，如果未找到则为默认值
        /// </returns>
        /// <remarks>
        /// 此方法仅尝试获取缓存值，不会触发缓存重建。
        /// 当缓存项不存在时，将返回 (false, default)
        /// </remarks>
        (bool Success, TItem? Value) TryGetValue<TItem>(string key);

        /// <summary>
        /// 异步尝试从缓存中获取指定键的值
        /// </summary>
        /// <typeparam name="TItem">缓存项的类型</typeparam>
        /// <param name="key">缓存键</param>
        /// <param name="token">取消令牌</param>
        /// <returns>
        /// 返回一个表示异步操作的任务，任务结果为元组，包含：
        /// - Success：表示是否成功获取到缓存项
        /// - Value：缓存项的值，如果未找到则为默认值
        /// </returns>
        /// <remarks>
        /// 此方法仅尝试获取缓存值，不会触发缓存重建。
        /// 当缓存项不存在时，将返回 (false, default)
        /// </remarks>
        Task<(bool Success, TItem? Value)> TryGetValueAsync<TItem>(string key, CancellationToken token = default);

        /// <summary>
        /// 异步获取缓存项，如果不存在则通过指定的委托获取数据并设置缓存。
        /// </summary>
        /// <typeparam name="TData">数据类型。</typeparam>
        /// <param name="key">缓存键。</param>
        /// <param name="acquire">获取数据的委托，可以返回null值。</param>
        /// <param name="cacheEntryOptions">缓存项配置选项。</param>
        /// <param name="token">取消令牌。</param>
        /// <returns>表示异步操作的任务，包含获取的数据。数据可能为null。</returns>
        Task<TData?> GetAsync<TData>(string key, Func<Task<TData?>> acquire, CacheEntryOptions? cacheEntryOptions = null, CancellationToken token = default);

        /// <summary>
        /// 异步获取缓存项，如果不存在则通过指定的委托获取数据并设置缓存。
        /// </summary>
        /// <typeparam name="TData">数据类型。</typeparam>
        /// <param name="key">缓存键。</param>
        /// <param name="acquire">获取数据的委托，可以返回null值。</param>
        /// <param name="cacheEntryOptions">缓存项配置选项。</param>
        /// <param name="token">取消令牌。</param>
        /// <returns>表示异步操作的任务，包含获取的数据。数据可能为null。</returns>
        Task<TData?> GetAsync<TData>(string key, Func<TData?> acquire, CacheEntryOptions? cacheEntryOptions = null, CancellationToken token = default);

        /// <summary>
        /// 获取缓存项，如果不存在则通过指定的委托获取数据并设置缓存。
        /// </summary>
        /// <typeparam name="TData">数据类型。</typeparam>
        /// <param name="key">缓存键。</param>
        /// <param name="acquire">获取数据的委托，可以返回null值。</param>
        /// <param name="cacheEntryOptions">缓存项配置选项。</param>
        /// <returns>获取的数据，可能为null。当返回null时会使用较短的过期时间进行缓存。</returns>
        TData? Get<TData>(string key, Func<TData?> acquire, CacheEntryOptions? cacheEntryOptions = null);

        /// <summary>
        /// 异步移除缓存项。
        /// </summary>
        /// <param name="key">缓存键。</param>
        /// <param name="token">取消令牌。</param>
        /// <returns>表示异步操作的任务。</returns>
        Task RemoveAsync(string key, CancellationToken token = default);

        /// <summary>
        /// 异步批量移除缓存项。
        /// </summary>
        /// <param name="keys">缓存键集合。</param>
        /// <param name="token">取消令牌。</param>
        /// <returns>表示异步操作的任务。</returns>
        Task RemoveAsync(IEnumerable<string> keys, CancellationToken token = default);

        /// <summary>
        /// 移除缓存项。
        /// </summary>
        /// <param name="key">缓存键。</param>
        void Remove(string key);

        /// <summary>
        /// 批量移除缓存项。
        /// </summary>
        /// <param name="keys">缓存键集合。</param>
        void Remove(IEnumerable<string> keys);

        /// <summary>
        /// 异步移除指定前缀的缓存项。
        /// </summary>
        /// <param name="prefix">缓存键前缀。</param>
        /// <param name="token">取消令牌。</param>
        /// <returns>表示异步操作的任务。</returns>
        Task RemoveByPrefixAsync(string prefix, CancellationToken token = default);

        /// <summary>
        /// 移除指定前缀的缓存项。
        /// </summary>
        /// <param name="prefix">缓存键前缀。</param>
        void RemoveByPrefix(string prefix);

        /// <summary>
        /// 异步清理所有缓存项。
        /// </summary>
        /// <param name="token">取消令牌。</param>
        /// <returns>表示异步操作的任务。</returns>
        Task ClearAsync(CancellationToken token = default);

        /// <summary>
        /// 清理所有缓存项。
        /// </summary>
        void Clear();

        /// <summary>
        /// 创建缓存项配置选项。
        /// </summary>
        /// <returns>缓存项配置选项。</returns>
        CacheEntryOptions CreateCacheEntryOptions();
    }
}